using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Splittergame.Model;

namespace Splittergame
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class MasterController : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        SplitterSystem splitterSystem;
        ExplosionSystem explosionSystem;      
        BallView ballview;
        Ballsimulation ballSimulation;
        Shockwave shockwave;
        SmokeSystem smokeSystem;
        KeyboardState currentKeyboardState;
        MouseState currentMouseState;
        MouseState oldMouseState;
        List<CombinedSystem> combindedList;
        Camera camera;

        private const int RES_HEIGHT = 600;
        private const int RES_WIDTH = 600;

        public MasterController()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        protected override void Initialize()
        {
            currentKeyboardState = new KeyboardState();
            currentMouseState = new MouseState();
            combindedList = new List<Model.CombinedSystem>();
            this.IsMouseVisible = true;
            SetResolution();

            base.Initialize();
        }


        protected override void LoadContent()
        {

            spriteBatch = new SpriteBatch(GraphicsDevice);
            if (splitterSystem != null && smokeSystem != null && shockwave != null)
            {
                splitterSystem.LoadContent(this.Content);
                smokeSystem.LoadContent(this.Content);
                shockwave.LoadContent(this.Content);
            }
            else if (splitterSystem != null)
            {
                splitterSystem.LoadContent(this.Content);
            }
            else if (smokeSystem != null)
            {
                smokeSystem.LoadContent(this.Content);
            }
            else if (explosionSystem != null)
            {
                explosionSystem.LoadContent(this.Content);
            }
            else if (combindedList.Count != 0)
            {
                ballSimulation.LoadContent();
                ballview.LoadContent(this.Content);

                foreach (CombinedSystem CS in combindedList)
                {
                    CS.LoadContent(this.Content);
                }                            
            }

            camera = new Camera(GraphicsDevice.Viewport);
        }
        protected override void UnloadContent()
        {

        }
        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            CheckInput();

            if (splitterSystem != null)
            {
                splitterSystem.Update(gameTime);
            }
            if (smokeSystem != null)
            {
                smokeSystem.Update(gameTime);
            }
            if (explosionSystem != null)
            {
                explosionSystem.Update(gameTime);
            }
            if (shockwave != null)
            {
                shockwave.Update(gameTime);
            }
            if (combindedList.Count != 0)
            {
                ballSimulation.Update(gameTime, currentMouseState, getMousePosition());

                foreach (CombinedSystem CS in combindedList)
                {
                    CS.Update(gameTime); 
                }           
            }

            base.Update(gameTime);
        }
        
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);

            spriteBatch.Begin();

            if (shockwave != null)
            {
                shockwave.Draw(spriteBatch, camera);
            }
            if (splitterSystem != null)
            {
                splitterSystem.Draw(spriteBatch, camera);
            }
            if (smokeSystem != null)
            {
                smokeSystem.Draw(spriteBatch, camera);
            }
            if (explosionSystem != null)
            {
                explosionSystem.Draw(spriteBatch, camera);
            }
            if (combindedList.Count != 0)
            {
                ballview.Draw(spriteBatch, camera);

                foreach (CombinedSystem CS in combindedList)
                {
                    CS.Draw(spriteBatch, camera);          
                }   
            }

            spriteBatch.End();

            base.Draw(gameTime);
        }
        protected void CheckInput()
        {

            currentKeyboardState = Keyboard.GetState();

            Vector2 StartPosition = getMousePosition();

            if (currentKeyboardState.IsKeyDown(Keys.Q))
            {
                splitterSystem = new SplitterSystem(StartPosition);
                smokeSystem = null;
                explosionSystem = null;
                LoadContent();
            }
            else if (currentKeyboardState.IsKeyDown(Keys.W))
            {
                smokeSystem = new SmokeSystem(StartPosition);
                splitterSystem = null;
                explosionSystem = null;               
                LoadContent();
            }
            else if (currentKeyboardState.IsKeyDown(Keys.E))
            {
                explosionSystem = new ExplosionSystem(StartPosition);
                splitterSystem = null;
                smokeSystem = null;                
                LoadContent();
            }
            else if (currentKeyboardState.IsKeyDown(Keys.R))
            {
                splitterSystem = new SplitterSystem(StartPosition);
                smokeSystem = new SmokeSystem(StartPosition);
                shockwave = new Shockwave(StartPosition);
                explosionSystem = null;
                LoadContent();
            }
            else if (currentKeyboardState.IsKeyDown(Keys.Space))
            {

                splitterSystem = null;
                smokeSystem = null;
                shockwave = null;
                explosionSystem = null;
                ballSimulation = new Ballsimulation();
                ballview = new BallView(ballSimulation);
                CombinedSystem CombinedSystem = new CombinedSystem(StartPosition);
                combindedList.Add(CombinedSystem);
                LoadContent();            
            }
            if (currentMouseState.LeftButton == ButtonState.Pressed)
            {
                if (combindedList.Count != 0)
                {
                    ballview.MakeSound();
                    ballSimulation.BallHit(getMousePosition());                            
                }
                
            }
            oldMouseState = currentMouseState;
        }

        private Vector2 getMousePosition()
        {
            currentMouseState = Mouse.GetState();
            Vector2 LogicalMousePosition;

            float scaleX = GraphicsDevice.Viewport.Width / 10;
            float scaleY = GraphicsDevice.Viewport.Height / 10;

            LogicalMousePosition.X = currentMouseState.X;
            LogicalMousePosition.Y = currentMouseState.Y;

            LogicalMousePosition.X = LogicalMousePosition.X / scaleX;
            LogicalMousePosition.Y = LogicalMousePosition.Y / scaleY;

            System.Diagnostics.Debug.WriteLine(LogicalMousePosition);

            return LogicalMousePosition;
        }
        private void SetResolution()
        {
        
            graphics.PreferredBackBufferHeight = RES_HEIGHT;
            graphics.PreferredBackBufferWidth = RES_WIDTH;
            graphics.ApplyChanges();

        }
    }
}
